package com.by.component.shortlink;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.by.component.shortlink.mapper.ShortLinkMapper;
import com.by.redis.enums.byRedisUtilityEnum;
import com.by.redis.support.byRedisSupport;
import com.by.toolkit.consts.RedisConst;
import com.by.toolkit.exceptions.ServiceException;
import com.by.toolkit.platform.byContext;
import com.by.toolkit.utils.ExceptionUtil;
import com.by.toolkit.utils.SplitterUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@DubboService
public class ShortLinkServiceImpl implements ShortLinkService {

    @Resource
    private ShortLinkMapper shortLinkMapper;

    @Resource
    private ShortLinkService shortLinkService;

    @Resource
    private byRedisSupport byRedisSupport;

    private static final String SHORT_LINK_TEMPLATE = "{}/s/{}";

    @Override
    public String generateShortKey(String oriVal, Long expireSecond) {
        StringBuilder shortKey = new StringBuilder(RandomUtil.randomString(6));

        if (oriVal.length() > 2000) {
            throw new ServiceException("原始链接长度不能超过2000");
        }

        Long shortId = shortLinkMapper.shortKeyRelaId(shortKey.toString());
        if (Objects.nonNull(shortId)) {
            for (int i = 0; i < 3; i++) {
                shortKey.append(RandomUtil.randomString(1));
            }
        }

        try {
            shortLinkMapper.insert(ShortLink.builder()
                    .shortKey(shortKey.toString())
                    .oriVal(oriVal)
                    .expireLongTime(expireSecond)
                    .build());
        } catch (Exception e) {
            if (ExceptionUtil.uqIndexError(e)) {
                log.warn("[ShortLinkServiceImpl][generateShortKey] shortKey:[{}] oriUrl:[{}] uqIndexError", shortKey, oriVal);
                return shortLinkService.generateShortKey(oriVal);
            }
            throw e;
        }

        // 放入缓存
        StringRedisTemplate redisTemplate = byRedisSupport.getStringRedisTemplate(byRedisUtilityEnum.COMMON);
        String key = SplitterUtil.EN_COLON_JOINER.join(RedisConst.SHORT_KEY_PREFIX, shortKey, byContext.getCorpCode(), byContext.getProjectId());
        redisTemplate.opsForValue().set(key, oriVal, 1, TimeUnit.DAYS);

        log.info("[ShortLinkServiceImpl][generateShortKey] success shortKey:[{}] oriUrl:[{}]", shortKey, oriVal);
        return shortKey.toString();

    }

    public String generateShortKey(String oriVal) {
        return this.generateShortKey(oriVal, Long.MAX_VALUE);
    }

    @Override
    public String oriVal(String shortKey) {
        return shortLinkMapper.oriVal(shortKey);
        /*StringRedisTemplate redisTemplate = byRedisSupport.getStringRedisTemplate(byRedisUtilityEnum.COMMON);

        String key = SplitterUtil.EN_COLON_JOINER.join(RedisConst.SHORT_KEY_PREFIX, shortKey, byContext.getCorpCode(), byContext.getProjectId());
        String retVal = redisTemplate.opsForValue().get(key);

        if (StringUtils.isNotBlank(retVal)) {
            return retVal;
        }

        retVal = shortLinkMapper.oriVal(shortKey);

        if (StringUtils.isNotBlank(retVal)) {
            redisTemplate.opsForValue().set(key, retVal, 1, TimeUnit.DAYS);
        }
        return retVal;*/
    }

    @Override
    public String generateShortLink(String domain, String oriVal) {
        String shortKey = shortLinkService.generateShortKey(oriVal);
        String shortLink = StrUtil.format(SHORT_LINK_TEMPLATE, domain, shortKey);
        log.info("[ShortLinkServiceImpl][generateShortLink] oriVal:[{}] shortKey:[{}] shortLink:[{}]", oriVal, shortKey, shortLink);
        return shortLink;
    }

}
